package fsmsim.buffer;

import fsmsim.dataStructure.Event;

/**
 * <p>Title: FSMSim</p>
 *
 * <p>Description: Simulatore di macchine a stati finiti.</p>
 *
 * <p>Copyright: Copyright (c) 2008</p>
 *
 * <p>Company: Bollati, Donati, Gabrielli, Peli</p>
 *
 * @author Bollati, Donati, Gabrielli, Peli
 * @version 3.0
 */

public class BufferFIFO extends Buffer {

    
    /**
     * Costruttore
     * @param policyType
     * @param dimension
     */

    public BufferFIFO(int policyType, int dimension) {
        super(policyType,dimension);
    }

    
    /**
     * Aggiunge evento al buffer FIFO
     * @param aEvent
     */

    public void addEvent(Event aEvent) {
        if (this.isFull()) {
            this.getPolicy().placeEventIntoBuffer(this, aEvent);
        } else {
            int i = this.getBuffer().size() - 1;
            while (this.getBuffer().getElement(i) != null) {
                i--;
            }
            this.addEvent(aEvent,i);
        }
       
    }

    
    /**
     * Torna true se il buffer è completamente vuoto
     * @return
     */

    public boolean isEmpty() {
        return this.getBuffer().getElement(this.getBuffer().size() - 1)  == null ? true : false;
    }

    
    /**
     * Torna true se il buffer è completamente pieno
     * @return
     */

    public boolean isFull() {
        return (this.getBuffer().getElement(0) != null ? true : false);
    }

    
    /**
     * Preleva un evento dal buffer
     * @return
     */

    public Event drawEvent() {
        // drawEvent il dato (oppure null)
        Event data = (Event)this.getBuffer().getElement(this.getBuffer().size()-1);

        // variabile temporanea per lo scorrimento
        Event temp;
        // primo dato da spostare
        int i = this.getBuffer().size() - 2;
        // fino alla fine
        while (i != -1) {
            // scambia
            temp = (Event)this.getBuffer().getElement(i);
            this.addEvent(temp, i + 1);
            i--;
        }
        // libera la posizione di entrata (FIFO)
        this.addEvent(null, i + 1);
        // ritorna il dato da prelevare (se ce n'erano)
        return data;
    }

    
    /**
     * Ritorna una copia del prossimo evento da prelevare dal buffer (senza
     * prelevarlo)
     * @return
     */

    public Event getEvent() {
        // ritorna il dato da prelevare (se ce n'erano)
        return (Event)this.getBuffer().getElement(this.getBuffer().size()-1);
    }

}
